const UserActivityLog = require('../models/userActivityLog.model');
const logger = require('../utils/logger');
const mongoose = require('mongoose');

/**
 * 活动日志服务
 * 提供记录用户活动的功能
 */
class ActivityLogService {
  /**
   * 记录用户活动
   * @param {Object} logData 日志数据
   * @param {string|ObjectId} logData.userId 用户ID
   * @param {string} logData.userType 用户类型 ('user'|'admin')
   * @param {string} logData.actionType 操作类型
   * @param {string} logData.module 操作模块
   * @param {Object} logData.details 操作详情
   * @param {string|ObjectId} [logData.details.object] 操作对象ID
   * @param {string} logData.details.description 操作描述
   * @param {*} [logData.details.oldValue] 操作前值
   * @param {*} [logData.details.newValue] 操作后值
   * @param {string} [logData.ipAddress] IP地址
   * @param {string} [logData.userAgent] 用户代理信息
   * @param {Object} [logData.deviceInfo] 设备信息
   * @param {string} [logData.status='success'] 操作状态
   * @param {string} [logData.errorMessage] 错误信息
   * @returns {Promise<Object>} 创建的日志记录
   */
  async logActivity(logData) {
    try {
      // 检查MongoDB连接状态
      if (mongoose.connection.readyState !== 1) {
        throw new Error('MongoDB连接未就绪');
      }

      // 确保必填字段存在
      if (!logData.actionType || !logData.module || !logData.details || !logData.details.description) {
        throw new Error('缺少必要的日志信息字段');
      }

      // 处理用户ID - 确保它是有效的ObjectId，如果不是则使用默认值
      let userId = 'unknown';
      if (logData.userId) {
        try {
          // 检查userId是否为有效的ObjectId
          if (mongoose.Types.ObjectId.isValid(logData.userId)) {
            userId = new mongoose.Types.ObjectId(logData.userId);
          } else {
            logger.warn(`无效的用户ID格式: ${logData.userId}，使用默认值`);
          }
        } catch (idError) {
          logger.warn(`处理用户ID时出错: ${idError.message}`);
        }
      }

      // 创建日志记录
      const activityLog = new UserActivityLog({
        userId: userId,
        userType: logData.userType || 'user',
        actionType: logData.actionType,
        module: logData.module,
        details: {
          object: logData.details.object ? (mongoose.Types.ObjectId.isValid(logData.details.object) ? new mongoose.Types.ObjectId(logData.details.object) : null) : null,
          description: logData.details.description,
          oldValue: this._sanitizeValue(logData.details.oldValue),
          newValue: this._sanitizeValue(logData.details.newValue)
        },
        ipAddress: logData.ipAddress || null,
        userAgent: logData.userAgent || null,
        deviceInfo: logData.deviceInfo || {},
        status: logData.status || 'success',
        errorMessage: logData.errorMessage || null
      });

      // 保存日志记录
      const savedLog = await activityLog.save();
      return savedLog;
    } catch (error) {
      // 记录服务错误但不中断应用流程
      logger.error(`记录用户活动失败: ${error.message}`, {
        error: error.stack,
        logData: this._sanitizeValue(logData)
      });
      
      // 尝试保存失败日志
      try {
        // 确保userId格式正确
        let userId = 'unknown';
        if (logData && logData.userId) {
          userId = mongoose.Types.ObjectId.isValid(logData.userId) ? new mongoose.Types.ObjectId(logData.userId) : 'unknown';
        }

        const failedLog = new UserActivityLog({
          userId: userId,
          userType: (logData && logData.userType) || 'user',
          actionType: 'error',
          module: 'activity_log',
          details: {
            description: `记录活动失败: ${error.message}`,
            oldValue: null,
            newValue: this._sanitizeValue(logData)
          },
          status: 'failed',
          errorMessage: error.message
        });
        await failedLog.save();
      } catch (saveError) {
        logger.error(`记录失败日志也失败: ${saveError.message}`, {
          originalError: error.message,
          saveError: saveError.stack
        });
      }
      
      return null;
    }
  }

  /**
   * 安全处理值，避免循环引用和无法序列化的数据
   * @private
   * @param {*} value 需要处理的值
   * @returns {*} 处理后的值
   */
  _sanitizeValue(value) {
    if (!value) return null;
    try {
      // 尝试通过JSON序列化和反序列化来清理数据
      return JSON.parse(JSON.stringify(value));
    } catch (error) {
      logger.warn(`值序列化失败: ${error.message}`);
      return String(value);
    }
  }

  /**
   * 批量记录用户活动
   * @param {Array<Object>} logDataArray 日志数据数组
   * @returns {Promise<Array>} 创建的日志记录数组
   */
  async logBatchActivity(logDataArray) {
    if (!Array.isArray(logDataArray) || logDataArray.length === 0) {
      return [];
    }

    const results = [];
    for (const logData of logDataArray) {
      const result = await this.logActivity(logData);
      if (result) {
        results.push(result);
      }
    }
    return results;
  }

  /**
   * 获取指定用户的活动日志
   * @param {string|ObjectId} userId 用户ID
   * @param {Object} options 查询选项
   * @param {number} [options.limit=20] 返回记录数量限制
   * @param {number} [options.skip=0] 跳过记录数量
   * @param {string} [options.module] 筛选指定模块
   * @param {string} [options.actionType] 筛选指定操作类型
   * @param {Date|string} [options.startDate] 开始日期
   * @param {Date|string} [options.endDate] 结束日期
   * @returns {Promise<Array>} 用户活动日志列表
   */
  async getUserActivityLogs(userId, options = {}) {
    const query = { userId };
    
    if (options.module) {
      query.module = options.module;
    }
    
    if (options.actionType) {
      query.actionType = options.actionType;
    }
    
    const dateQuery = {};
    if (options.startDate) {
      dateQuery.$gte = new Date(options.startDate);
    }
    
    if (options.endDate) {
      dateQuery.$lte = new Date(options.endDate);
    }
    
    if (Object.keys(dateQuery).length > 0) {
      query.createdAt = dateQuery;
    }
    
    const limit = options.limit || 20;
    const skip = options.skip || 0;
    
    return UserActivityLog.find(query)
      .sort({ createdAt: -1 })
      .limit(limit)
      .skip(skip)
      .exec();
  }

  /**
   * 获取系统活动日志
   * @param {Object} options 查询选项
   * @param {number} [options.limit=20] 返回记录数量限制
   * @param {number} [options.skip=0] 跳过记录数量
   * @param {string} [options.module] 筛选指定模块
   * @param {string} [options.actionType] 筛选指定操作类型
   * @param {string} [options.userType] 筛选指定用户类型
   * @param {Date|string} [options.startDate] 开始日期
   * @param {Date|string} [options.endDate] 结束日期
   * @param {string} [options.status] 筛选指定状态
   * @returns {Promise<Array>} 系统活动日志列表
   */
  async getSystemActivityLogs(options = {}) {
    const query = {};
    
    if (options.module) {
      query.module = options.module;
    }
    
    if (options.actionType) {
      query.actionType = options.actionType;
    }
    
    if (options.userType) {
      query.userType = options.userType;
    }
    
    if (options.status) {
      query.status = options.status;
    }
    
    const dateQuery = {};
    if (options.startDate) {
      dateQuery.$gte = new Date(options.startDate);
    }
    
    if (options.endDate) {
      dateQuery.$lte = new Date(options.endDate);
    }
    
    if (Object.keys(dateQuery).length > 0) {
      query.createdAt = dateQuery;
    }
    
    const limit = options.limit || 20;
    const skip = options.skip || 0;
    
    return UserActivityLog.find(query)
      .sort({ createdAt: -1 })
      .limit(limit)
      .skip(skip)
      .exec();
  }
}

module.exports = new ActivityLogService(); 